package com.lizard.schedule.ui.adapter.schedule;

import android.app.Activity;
import android.content.Intent;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.lizard.schedule.R;
import com.lizard.schedule.manager.AccountManager;
import com.lizard.schedule.manager.ScheduleSyncManager;
import com.lizard.schedule.manager.observer.ObserverManager;
import com.lizard.schedule.net.http.request.bean.ScheduleSync.ScheduleSyncItem;
import com.lizard.schedule.persistence.db.bean.Schedule;
import com.lizard.schedule.persistence.db.table.ScheduleTbl;
import com.lizard.schedule.ui.activity.EditScheduleActivity;
import com.lizard.schedule.ui.view.schedulelist.ScheduleItemLinearLayout;
import com.lizard.schedule.ui.view.schedulelist.ScheduleListView;
import com.lizard.schedule.wear.Sender;
import com.lizard.schedule.widget.ScheduleAlertDialog;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class ScheduleListAdapter extends BaseAdapter implements AdapterView.OnItemClickListener{

    /**
     * 排序方式-未来计划:时间从小到大、id从小到大
     */
    public static int SORT_BY_FUTURE = 1;
    /**
     * 排序方式-历史计划：时间从大到小、id从大到小
     */
    public static int SORT_BY_HISTORY = 2;
    private final String TAG = ScheduleListAdapter.class.getSimpleName();
    private List<ScheduleFacade> mScheduleFacades = new ArrayList<ScheduleFacade>();

    private Activity mActivity;

    private LayoutInflater mInflater;

    /**
     * 集合排序比较器
     */
    private ScheduleComparetor mScheduleComparetor;

    private ScheduleListView mScheduleListView;

    public ScheduleListAdapter(Activity activity, ScheduleListView scheduleListView, int sortBy){
        mActivity = activity;
        mScheduleListView = scheduleListView;
        mInflater = LayoutInflater.from(mActivity);
        mScheduleComparetor = new ScheduleComparetor(sortBy);
    }

    /**
     * 更新Schedule对象的submited状态、更新serverId、不刷新界面
     *
     * @param submitedLocalIds
     * @param addedServerIds
     */
    public void setSubmitedAndServerIdWithoutNotify(List<Integer> submitedLocalIds, Map<Integer, Long> addedServerIds){
        for(ScheduleFacade scheduleFacade: mScheduleFacades){
            if(submitedLocalIds != null
                    && submitedLocalIds.contains(scheduleFacade.getSchedule().getLocalId())){
                scheduleFacade.getSchedule().setSubmited(true);
            }

            if(addedServerIds != null
                    && addedServerIds.containsKey(scheduleFacade.getSchedule().getLocalId())){
                scheduleFacade.getSchedule().setServerId(addedServerIds.get(scheduleFacade.getSchedule().getLocalId()));
            }
        }
    }

    /**
     * 清除数据但不刷新界面
     */
    public void clearWithOutNotify(){
        mScheduleFacades.clear();
    }

    /**
     * 设置Schedule集合
     *
     * @param schedules
     */
    public void setData(List<Schedule> schedules){
        mScheduleFacades.clear();
        addData(schedules);
    }

    /**
     * 界面上是否存在该计划
     *
     * @param scheduleLocalId
     * @return
     */
    public boolean existData(int scheduleLocalId){
        boolean exist = false;
        for(ScheduleFacade scheduleFacade: mScheduleFacades){
            if(scheduleFacade.getSchedule().getLocalId() == scheduleLocalId){
                exist = true;
                break;
            }
        }
        return exist;
    }

    /**
     * 添加Schedule集合
     * @param schedules
     */
    public void addData(List<Schedule> schedules){
        if(schedules != null){
            List<ScheduleFacade> scheduleFacades = new ArrayList<ScheduleFacade>();
            for(Schedule schedule: schedules){
                scheduleFacades.add(new ScheduleFacade(schedule));
            }
            mScheduleFacades.addAll(scheduleFacades);
            sort();
            notifyDataSetChanged();
        }
    }

    /**
     * 添加Schedule
     *
     * @param schedule
     */
    public void addData(Schedule schedule){
        if(schedule != null){
            List<Schedule> schedules = new ArrayList<Schedule>();
            schedules.add(schedule);
            addData(schedules);
        }
    }

    /**
     * 更新数据
     *
     * @param schedule
     */
    public void updateData(Schedule schedule){
        if(schedule != null){
            for(int i = 0; i < mScheduleFacades.size(); i++){
                if(mScheduleFacades.get(i).getSchedule().getLocalId() == schedule.getLocalId()){
                    mScheduleFacades.set(i, new ScheduleFacade(schedule));
                    sort();
                    notifyDataSetChanged();
                    break;
                }
            }
        }
    }

    /**
     * 移除数据
     *
     * @param scheduleId
     */
    public void removeData(int scheduleId){
        for(int i = 0; i < mScheduleFacades.size(); i++){
            if(mScheduleFacades.get(i).getSchedule().getLocalId() == scheduleId){
                mScheduleFacades.remove(i);
                notifyDataSetChanged();
                break;
            }
        }
    }

    /**
     * 获取最后一条数据
     *
     * @return
     */
    private ScheduleFacade getLastData(){
        ScheduleFacade scheduleFacade = null;
        if(mScheduleFacades.size() > 0) {
            scheduleFacade = mScheduleFacades.get(mScheduleFacades.size() - 1);
        }
        return scheduleFacade;
    }

    /**
     * 获取最后一条Schedule
     *
     * @return
     */
    public Schedule getLastSchedule(){
        Schedule schedule = null;
        ScheduleFacade scheduleFacade = getLastData();
        if(scheduleFacade != null){
            schedule = scheduleFacade.getSchedule();
        }
        return schedule;
    }

    /**
     * 数据排序
     */
    private void sort(){
        Collections.sort(mScheduleFacades, mScheduleComparetor);
    }

    @Override
    public int getCount() {
        return mScheduleFacades.size();
    }

    @Override
    public Object getItem(int position) {
        ScheduleFacade scheduleFacade = null;
        if(position >= 0 && position < mScheduleFacades.size()){
            scheduleFacade = mScheduleFacades.get(position);
        }
        return scheduleFacade;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Holder holder;
        if(convertView == null){
            convertView = mInflater.inflate(R.layout.my_schedule_item, parent , false);
            holder = new Holder();
            holder.date = (TextView) convertView.findViewById(R.id.date);
            holder.time = (TextView) convertView.findViewById(R.id.time);
            holder.dayOfWeek = (TextView) convertView.findViewById(R.id.day_of_week);
            holder.text = (TextView) convertView.findViewById(R.id.text);
            holder.timeFrame = convertView.findViewById(R.id.item_left);
            holder.delete = convertView.findViewById(R.id.delete);
            holder.finish = convertView.findViewById(R.id.finish);
            holder.finishTxt = (TextView) convertView.findViewById(R.id.finish_txt);
            holder.finishedFlag = convertView.findViewById(R.id.finished_flag);
            holder.dayNearBy = (TextView) convertView.findViewById(R.id.day_nearby);
            holder.repeatFlag = convertView.findViewById(R.id.repeat_flag);
            convertView.setTag(holder);
        } else{
            holder = (Holder)convertView.getTag();
        }

        ScheduleFacade scheduleFacade = (ScheduleFacade) getItem(position);

        holder.date.setText(scheduleFacade.getDateStr());
        holder.time.setText(scheduleFacade.getTimeStr());
        holder.text.setText(scheduleFacade.getSchedule().getContentText());
        holder.finishedFlag.setVisibility(scheduleFacade.getSchedule().getStatus() == Schedule.STATUS_FINISHED ? View.VISIBLE : View.GONE);
        holder.dayOfWeek.setText(scheduleFacade.getDayOfWeekName());

        // 判断如果和下一条时间是同一天 则时间栏底部无分割线
        ScheduleFacade nextScheduleFacade = (ScheduleFacade) getItem(position + 1);
        if(nextScheduleFacade != null
                && nextScheduleFacade.getSchedule() != null
                && nextScheduleFacade.getDateStr().equals(scheduleFacade.getDateStr())){
            holder.timeFrame.setBackgroundColor(mActivity.getResources().getColor(R.color.white));
        } else{
            holder.timeFrame.setBackgroundColor(mActivity.getResources().getColor(R.color.common_transparent));
        }

        // 判断如果和上一条时间是同一天 则不显示日期和周
        ScheduleFacade preScheduleFacade = (ScheduleFacade) getItem(position - 1);
        if(preScheduleFacade != null
                && preScheduleFacade.getSchedule() != null
                && preScheduleFacade.getDateStr().equals(scheduleFacade.getDateStr())){
            holder.date.setVisibility(View.GONE);
            holder.dayOfWeek.setVisibility(View.GONE);
            holder.dayNearBy.setVisibility(View.GONE);

        } else{
            holder.date.setVisibility(View.VISIBLE);
            holder.dayOfWeek.setVisibility(View.VISIBLE);

            // 今、明、后、昨、前 标记
            holder.dayNearBy.setVisibility(
                    TextUtils.isEmpty(scheduleFacade.getBrefDayNearby()) ?
                            View.GONE : View.VISIBLE);
            holder.dayNearBy.setText(scheduleFacade.getBrefDayNearby());
        }

        // 屏幕外的按钮点设置
        setExtraOptionsBtns(holder, scheduleFacade);

        // 重复标记的显示
        holder.repeatFlag.setVisibility(scheduleFacade.getSchedule().getRepeat() == ScheduleSyncItem.REPEAT_NONE ? View.GONE : View.VISIBLE);

        return convertView;
    }

    /**
     * 屏幕外的按钮设置
     *
     * @param holder
     * @param scheduleFacade
     */
    private void setExtraOptionsBtns(Holder holder, final ScheduleFacade scheduleFacade){

        if(scheduleFacade.getSchedule().getStatus() == Schedule.STATUS_UNFINISHED){
            holder.finishTxt.setText(R.string.finish);
        } else{
            holder.finishTxt.setText(R.string.cancel_finish);
        }

        holder.finish.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                mScheduleListView.closeAllItemOptions();

                // 标记为已结束/未结束
                Schedule schedule = (Schedule) scheduleFacade.getSchedule().clone();
                schedule.setStatus(schedule.getStatus() == Schedule.STATUS_UNFINISHED ? Schedule.STATUS_FINISHED : Schedule.STATUS_UNFINISHED);
                schedule.setSubmited(false);

                // 数据库更新
                ScheduleTbl.getInstance().update(AccountManager.getInstance().getmUsernameMD5L16(), schedule);

                // 通知界面修改了Schedule数据
                ObserverManager.getInstance().notifyUpdateScheduleToUis(schedule);

                // 去同步
                ScheduleSyncManager.getInstance().sync(null);

                // wear同步
                Sender.sendSchedules();
            }
        });

        holder.delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                mScheduleListView.closeAllItemOptions();

                new ScheduleAlertDialog.Builder(mActivity)
                        .setMessage(R.string.sure_to_delete)
                        .setPositiveButton(R.string.confirm, new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {

                                // 标记为删除
                                Schedule schedule = (Schedule) scheduleFacade.getSchedule().clone();
                                schedule.setDeleted(true);
                                schedule.setSubmited(false);

                                // 数据库更新
                                ScheduleTbl.getInstance().update(AccountManager.getInstance().getmUsernameMD5L16(), schedule);

                                // 通知界面修改了Schedule数据
                                ObserverManager.getInstance().notifyUpdateScheduleToUis(schedule);

                                // 去同步
                                ScheduleSyncManager.getInstance().sync(null);

                                // wear同步
                                Sender.sendSchedules();

                            }
                        })
                        .setNegativeButton(R.string.cancel, null)
                        .show();

            }
        });
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        final ScheduleFacade scheduleFacade = (ScheduleFacade)adapterView.getAdapter().getItem(i);
        if(scheduleFacade == null){
            return;
        }

        if(view instanceof ScheduleItemLinearLayout){
            ScheduleItemLinearLayout scheduleItemLinearLayout = (ScheduleItemLinearLayout) view;
            if(scheduleItemLinearLayout.isOptionsOpen()){
                scheduleItemLinearLayout.closeOptions();;
                return;
            }
        }

        mScheduleListView.closeAllItemOptions();

        Intent intent = new Intent(mActivity, EditScheduleActivity.class);
        intent.setAction(EditScheduleActivity.ACTION_MODIFY);
        intent.putExtra(EditScheduleActivity.EXTRA_ORIGINAL_SCHEDULE, scheduleFacade.getSchedule());
        mActivity.startActivity(intent);
    }

    class Holder{
        TextView date;
        TextView time;
        TextView dayOfWeek;
        TextView text;
        View timeFrame;
        View finish;
        View delete;
        TextView finishTxt;
        View finishedFlag;
        TextView dayNearBy;
        View repeatFlag;
    }

}
